package info.niwota.start;

import info.niwota.start.app.AppLoader;
import info.niwota.start.help.WebViewActivity;

import java.util.List;

import android.app.Dialog;
import android.app.ExpandableListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;

/**
 * 
Start your applications from here.
Instead of going home, start apps from status bar.

Create and add apps in user folders with special name: 
Statusbar - start from pulldown notifications.
Favorite - show in favorite group menu. 
Startup - auto start at boot time.
Start uses internal API and may not work on all devices.
 *
 * @author qiangli
 *
 */
public class StartActivity extends ExpandableListActivity implements
		View.OnCreateContextMenuListener {

	private static final String TAG = "StartActivity";

	public static final int GROUP_STARRED = 0;
	public static final int GROUP_RECENT = 1; //
	public static final int GROUP_ALL = 2; // 
	
	private static final int RC_SETTINGS = 1;

	private AppExpandableListAdapter mAdapter;

	private boolean needsReload;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		// requestWindowFeature(Window.FEATURE_LEFT_ICON);
		requestWindowFeature(Window.FEATURE_NO_TITLE);

		setContentView(R.layout.main);

		ExpandableListView lv = getExpandableListView();
		lv.setFastScrollEnabled(false);
		lv.setOnCreateContextMenuListener(this);
		lv.setTextFilterEnabled(true);
		//
		mAdapter = (AppExpandableListAdapter) getLastNonConfigurationInstance();
		final Context ctx = this;
		if (mAdapter == null) {
			final int entries = R.array.folder_entries_basic;
			mAdapter = new AppExpandableListAdapter(ctx, entries) {
				@Override
				protected List<? extends Object> load(int group) {
					switch(group) {
					case 0:
						return AppLoader.loadStarred(ctx);
					case 1:
						return AppLoader.loadRecent(ctx);
					case 2:
						return AppLoader.loadAll(ctx);
					}
					return null;
				}
			};
		}
		setListAdapter(mAdapter);
		Resources res = getResources();
		Drawable ind = res.getDrawable(R.drawable.expander_group);
		lv.setGroupIndicator(ind);
		
		setRunningStatus(true);
		//
//		if (savedInstanceState == null) {
//			try {
//				Utils.addNotification(this);
//			} catch (Exception e) {
//				if (Debug.DEBUG) {
//					e.printStackTrace();
//				}
//			}
//		}
	}

	@Override
	public Object onRetainNonConfigurationInstance() {
		return mAdapter;
	}

	@Override
	public void onSaveInstanceState(Bundle outcicle) {
		super.onSaveInstanceState(outcicle);
	}

	@Override
	public void onDestroy() {
		setListAdapter(null);
		mAdapter = null;

		super.onDestroy();
	}

	@Override
	public void onResume() {
		super.onResume();
		if (Debug.DEBUG) {
			Log.d(TAG, "onResume");
		}
		if (mAdapter != null && needsReload) {
			needsReload = false;
			reload();
		}
		
		if (needsReload) {
			Notifications.update(this);
		}
	}

	private void reload() {
		mAdapter.load(GROUP_STARRED);
		mAdapter.load(GROUP_RECENT);
		mAdapter.notifyDataSetChanged();
	}

	@Override
	public void onPause() {
		super.onPause();
		
		if (Debug.DEBUG) {
			Log.d(TAG, "onPause");
		}
	}

	@Override
	public void onGroupCollapse(int groupPosition) {
		if (Debug.DEBUG) {
			Log.d(TAG, "onGroupCollapse " + groupPosition);
		}
		super.onGroupCollapse(groupPosition);
	}

	@Override
	public void onGroupExpand(int groupPosition) {
		if (Debug.DEBUG) {
			Log.d(TAG, "onGroupExpand " + groupPosition);
		}
		super.onGroupExpand(groupPosition);
	}

	@Override
	public boolean onChildClick(ExpandableListView parent, View v,
			int groupPosition, int childPosition, long id) {
		ArrayCursor c = mAdapter.getChild(groupPosition, childPosition);
		ResourceInfo ri = (ResourceInfo) c.getObject();
//		
//		if (groupPosition == FolderHelper.GROUP_USERFOLDER) {
//			showUserFolderDialog(ri);
//			return true;
//		}
//		
		if (ri != null) {
			Intent i = ri.getIntent();
			if (i != null) {
				startActivity(i);
				//
				doHibernate();
				return true;
			}
		}
		// Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
		return true;
	}

	private void doHibernate() {
		//
		finish();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.start_options, menu);
		//
		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.start_help_opt_menu_id:
			doHelp();
			return true;
		case R.id.start_settings_opt_menu_id:
			doSettings();
			return true;
		case R.id.start_quit_opt_menu_id:
			doQuit();
			return true;
		default:
		}
		return false;
	}

	private void doHelp() {
		WebViewActivity.help(this);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			// cancel only
			finish();
			return true;
		} else {
			return super.onKeyDown(keyCode, event);
		}
	}

	private void doQuit() {
		setRunningStatus(false);
		//
		finish();
	}

	private void doSettings() {
		try {
			Intent i = new Intent(this, SettingsActivity.class);
			startActivityForResult(i, RC_SETTINGS);
			needsReload = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View view,
			ContextMenuInfo menuInfoIn) {
		// TODO inflate
		ExpandableListContextMenuInfo mi = (ExpandableListContextMenuInfo) menuInfoIn;

		int itemtype = ExpandableListView
				.getPackedPositionType(mi.packedPosition);
		int gpos = ExpandableListView.getPackedPositionGroup(mi.packedPosition);
		int cpos = ExpandableListView.getPackedPositionChild(mi.packedPosition);
		if (itemtype == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
			if (gpos == -1) {
				// this shouldn't happen
				Log.d(TAG, "no group");
				return;
			}
			// gpos = gpos - getExpandableListView().getHeaderViewsCount();
			// menu.setHeaderTitle(GROUPS[gpos]);
			return;
		} else if (itemtype == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
			if (cpos == -1) {
				// this shouldn't happen
				Log.d(TAG, "no child");
				return;
			}
			// gpos = gpos - getExpandableListView().getHeaderViewsCount();
			// menu.setHeaderTitle(GROUPS[gpos]);
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		return null;
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		return true;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode,
			Intent intent) {
		if (Debug.DEBUG) {
			Log.d(TAG, "onActivityResult requestCode: " + requestCode + " resultCode: " + resultCode + " data: " + intent);
		}
	}

	private void setRunningStatus(boolean b) {
		//app is considered running until explicitly exited
		final Context ctx = this;
		if (b) {
			Preferences.updateRunningStatus(ctx, true);
			Notifications.add(ctx);
			
			if (Preferences.enablePowerFeature(ctx)) {
				ScreenService.startup(this);
			}
		} else {
			Preferences.updateRunningStatus(ctx, false);
			Notifications.remove(ctx);
			
			ScreenService.shutdown(ctx);
		}
	}

	@Override
	protected void onNewIntent(Intent intent) {
		if (Debug.DEBUG) {
			Log.d(TAG, "onNewIntent: " + intent);
		}
		super.onNewIntent(intent);
	}

	public static void ensureRunning(Context ctx) {

		final boolean b = Preferences.getRunningStatus(ctx);		

		if (Debug.DEBUG) {
			Log.d(TAG, "ensureRunning. was running? " + b );
		}
		
		if (b) {
			try {
				Intent ezb = new Intent(ctx, StartActivity.class);
				ezb.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				ctx.startActivity(ezb);
			} catch (Exception e) {
				if (Debug.DEBUG) {
					e.printStackTrace();
				}
			}
		}
	}

}
